using AuthorCenter.Repository;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace AuthorCenter
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();

            // Microsoft.AspNetCore.Authentication，是所有认证实现的公共抽象类，它定义了实现认证Handler的规范，并包含一些方法，如令牌加密，序列化等
            // AddAuthentication 便是其提供的统一的注册认证服务的扩展方法

            // Microsoft.AspNetCore.Authentication.Cookie
            // Microsoft.AspNetCore.Authentication.JwtBearer
            // Microsoft.AspNetCore.Authentication.OAuth
            // Microsoft.AspNetCore.Authentication.OpenIdConnect
            // 源码 AuthenticationBuilder - 注册方案的同时注册对应的认证Handler
            services.AddAuthentication(options =>
            {
                // Cookie
                // 只配置了DefaultScheme，这样DefaultSignInScheme, DefaultSignOutScheme, DefaultChallengeScheme, DefaultForbidScheme 等都会使用该 Scheme 作为默认值
                options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;

                // 默认认证失败时启用oidc方案
                options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
                // 在本地验证中，身份令牌的发放与认证通常是由同一个服务器来完成，这也是我们比较熟悉的场景，对于Cookie, JwtBearer等认证来说，都属于是本地验证。
                // 而当我们使用OAuth, OIDC等验证方式时，身份令牌的发放则是由独立的服务或是第三方（QQ, Weibo 等）认证来提供，
                // 此时在我们的应用程序中获取身份令牌时需要请求远程服务器，因此称之为远程验证。
            })
            .AddCookie(options => 
            {
                // 在这里可以根据需要添加一些Cookie认证相关的配置。
            });


            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
            services.AddSingleton<UserStore>();
            //    .AddOpenIdConnect(o =>
            //    {
            //        o.ClientId = "server.hybrid";
            //        o.ClientSecret = "secret";
            //        o.Authority = "https://demo.identityserver.io/";
            //        o.ResponseType = OpenIdConnectResponseType.CodeIdToken;
            //    });
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            // AuthenticationMiddleware,执行我们注册的所有认证Handler
            app.UseAuthentication();
            app.UseRouting();
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}